package com.tanhua.dubbo.api;

import com.mongodb.client.result.DeleteResult;
import com.tanhua.commons.utils.Constants;
import com.tanhua.model.enums.CommentType;
import com.tanhua.model.mongo.Comment;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.vo.PageResult;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.List;

@DubboService
public class CommentApiImpl implements CommentApi {

    @Autowired
    private MongoTemplate mongoTemplate;


    @Override
    //发布评论--视频，并获取评论数量
    public Integer save(Comment comment) {

        //1、查询动态
        Movement movement = mongoTemplate.findById(comment.getPublishId(), Movement.class);
        //2、向comment对象设置被评论人属性11
        if (movement != null) {
            comment.setPublishUserId(movement.getUserId());
        }
        //3、保存到数据库
        mongoTemplate.save(comment);
        //4、更新动态表中的对应字段
        Query query = Query.query(Criteria.where("id").is(comment.getPublishId()));
        Update update = new Update();
        if (comment.getCommentType() == CommentType.LIKE.getType()) {
            update.inc("likeCount", 1);
        } else if (comment.getCommentType() == CommentType.COMMENT.getType()) {
            update.inc("commentCount", 1);
        } else {
            update.inc("loveCount", 1);
        }
        //设置更新参数
        FindAndModifyOptions options = new FindAndModifyOptions();
        options.returnNew(true);//获取更新后的最新数据
        Movement modify = mongoTemplate.findAndModify(query, update, options, Movement.class);
        //5、获取最新的评论数量，并返回
        return modify.statisCount(comment.getCommentType());
    }


    //删除
    @Override
    public Integer delete(Comment comment) {
        //1、删除Comment表数据
        Criteria criteria = Criteria.where("userId").is(comment.getUserId())
                .and("publishId").is(comment.getPublishId())
                .and("commentType").is(comment.getCommentType());
        Query query = Query.query(criteria);
        mongoTemplate.remove(query, Comment.class);
        //2、修改动态表中的总数量
        Query movementQuery = Query.query(Criteria.where("id").is(comment.getPublishId()));
        Update update = new Update();
        if (comment.getCommentType() == CommentType.LIKE.getType()) {
            update.inc("likeCount", -1);
        } else if (comment.getCommentType() == CommentType.COMMENT.getType()) {
            update.inc("commentCount", -1);
        } else {
            update.inc("loveCount", -1);
        }
        //设置更新参数
        FindAndModifyOptions options = new FindAndModifyOptions();
        options.returnNew(true);//获取更新后的最新数据
        Movement modify = mongoTemplate.findAndModify(movementQuery, update, options, Movement.class);
        //5、获取最新的评论数量，并返回
        return modify.statisCount(comment.getCommentType());
    }

    //分页查询
    @Override
    public PageResult comments(Integer page, Integer pagesize, Long movementId) {
        //1.构造条件
        Query query = Query.query(Criteria.where("publishId").is(movementId));
        //2.查询count
        long count = mongoTemplate.count(query, Long.class);
        //3.查询分页列表
        query.skip((page - 1) * pagesize).limit(pagesize).with(Sort.by(Sort.Order.desc("created")));
        List<Comment> list = mongoTemplate.find(query, Comment.class);
        //4.构建返回 PageResult
        return new PageResult(page, pagesize, count, list);
    }

    //分页查询  -- 马岩松
    @Override
    public List<Comment> findComments(String movementId, CommentType commentType, Integer page, Integer pagesize) {
        //1、构造查询条件
        Query query = Query.query(Criteria.where("publishId").is(new ObjectId(movementId)).and("commentType")
                        .is(CommentType.COMMENT.getType()))     //commentType.getType())
                .skip((page - 1) * pagesize)
                .limit(pagesize)
                .with(Sort.by(Sort.Order.desc("created")));
        //2、查询并返回
        return mongoTemplate.find(query, Comment.class);
    }


    //判断comment数据是否存在  -- 马岩松
    @Override
    public Boolean hasComment(String movementId, Long userId, CommentType commentType) {
        Criteria criteria = Criteria.where("userId").is(userId)
                .and("publishId").is(new ObjectId(movementId))
                .and("commentType").is(commentType.getType());
        Query query = Query.query(criteria);
        return mongoTemplate.exists(query, Comment.class); //判断数据是否存在
    }

    // -- 马岩松
    @Override
    public Comment likezan(String id) {
        return mongoTemplate.findById(new ObjectId(id), Comment.class);
    }

    /**
     * 说明:  评论点赞数据的更新与获取点赞值
     * 【视频/动态 相关评论的点赞和取消点赞接口通用】  慎改！！！！
     *
     * @param commentId 动态id
     * @param i         修改的幅度值 +-1
     * @return java.lang.Integer
     * @author 李磊
     * @since 2022-01-18 09:55
     */
    @Override
    public Integer countReview(String commentId, Integer i) {
        Query query = Query.query(Criteria.where("id").is(new ObjectId(commentId)));
        Update update = new Update();
        update.inc("likeCount", i);
        FindAndModifyOptions options = new FindAndModifyOptions();
        options.returnNew(true);
        Comment comment = mongoTemplate.findAndModify(query, update, options, Comment.class);
        return comment.getLikeCount();
    }

    //评论点赞 王东阳
    @Override
    public boolean saveLikeComment(Long userId, String publishId) {
        //查询当前用户对该条圈子的点赞数，判断当前用户是否已经点赞
        /*        *//*
        判当前评论是否被此用户点赞
         *//*
        String key = Constants.MOVEMENT_COMMENT_LIKE + userId;
        String value = Constants.MOVEMENT_COMMENT_LIKE_HASHKEY + publishId;

        if (redisTemplate.opsForHash().hasKey(key, value)) {
            return true;
        }
        //没点赞进行点赞数的查询--根据评论id进行评论查询

     */

        Query query = Query.query(Criteria.where("publishId")
                .is(new ObjectId(publishId))
                .and("commentType")
                .is(1).and("userId")
                .is(userId));
        long count = mongoTemplate.count(query, Comment.class);
        Comment one = mongoTemplate.findOne(Query.query(Criteria.where("id").is(publishId)), Comment.class);
        //判断是否已经进行了点赞操作
        if (count > 0) {
            return false;
        }
        //保存点赞记录 到数据库中
        Comment comment = new Comment();
        comment.setPublishId(one.getPublishId());  //需要进行格式的转换
        comment.setCommentType(1);
        comment.setContent(null);
        comment.setUserId(userId);
        comment.setCreated(System.currentTimeMillis());
        save(comment);
        return true;
    }

    //评论点赞-取消 王东阳
    @Override
    public boolean removeComment(Long userId, String publishId, int commentType) {
        Query query = Query.query(Criteria.where("userId").is(userId)
                .and("publishId")
                .is(new ObjectId(publishId))
                .and("commentType").is(commentType));
        //TODO 如果同一个人对同一个圈子进行了多次评论，是否会一次性删除了该用户对该圈子的所有的评论 bug
        DeleteResult remove = mongoTemplate.remove(query, Comment.class);
        //如果删除的数量大于0，表明删除成功，返回true
        return remove.getDeletedCount() > 0;
    }

    //查看评论数量  王东阳
    @Override
    public Long queryCommentCount(String publishId, int type) {
        Query query = Query.query(Criteria.where("publishId").is(new ObjectId(publishId)).and("commentType").is(type));
        long count = mongoTemplate.count(query, Comment.class);
        return count;
    }
    //获取用户动态
    @Override
    public List<Comment> select(Long userId, int id, Integer page, Integer pagesize) {
        Query q = Query.query(Criteria.where("publishUserId").is(id).and("commentType").is(id))
                .skip((page - 1)*pagesize).limit(pagesize);
        List<Comment> list = mongoTemplate.find(q, Comment.class);
        return list;
    }
}
